package com.springboot.dubbo.consumer.filter;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.rpc.*;
import com.springboot.dubbo.consumer.utils.AbstractMyThreadContext;
import com.springboot.dubbo.consumer.utils.AbstractUUIDShort;
import org.slf4j.MDC;

/**
 * @Author: guodong
 * @Date: 2020/10/16 14:07
 * @Version: 1.0
 * @Description:
 */
@Activate(group = {Constants.CONSUMER, Constants.PROVIDER}, order = -30000)
public class RemoteTraceIdFilter implements Filter {


    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        //判断是消费者  还是 服务提供者
        if (RpcContext.getContext().isConsumerSide()) {
            //消费者 将trace_id（业务流水号） set至上下文中
            RpcContext.getContext().setAttachment(AbstractMyThreadContext.TRACE_ID, AbstractMyThreadContext.getTraceId());
        } else {
            //取出业务流水号
            String traceId = RpcContext.getContext().getAttachment(AbstractMyThreadContext.TRACE_ID);
            if (traceId == null) {
                traceId = AbstractUUIDShort.generate();
            }
            //流水号set至线程局部变量
            AbstractMyThreadContext.setTraceId(traceId);
            //slf4j 中设置了日志打印格式用作日志链路追踪
            MDC.put(AbstractMyThreadContext.MDC_TRACE_ID, traceId);
        }
        try {
            return invoker.invoke(invocation);
        } finally {
            if (RpcContext.getContext().isProviderSide()) {
                MDC.remove(AbstractMyThreadContext.MDC_TRACE_ID);
                AbstractMyThreadContext.removeTraceId();
            }
        }
    }


}
